l1pte_propagate_from_guest(
d, &l1_pgentry_val(nl1e), &l1_pgentry_val(sl1e[i]));
- if ( unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT) )
- put_page_from_l1e(ol1e, d);
+ put_page_from_l1e(ol1e, d);
}
unmap_domain_mem(pl1e);
struct domain *d = current->domain;
/* Aligned access only, thank you. */
- if ( (addr & (bytes-1)) != 0 )
+ if ( !access_ok(VERIFY_WRITE, addr, bytes) || ((addr & (bytes-1)) != 0) )
{
MEM_LOG("ptwr_emulate: Unaligned or bad size ptwr access (%d, %p)\n",
bytes, addr);
/* We are looking only for read-only mappings of p.t. pages. */
if ( ((pte & (_PAGE_RW | _PAGE_PRESENT)) != _PAGE_PRESENT) ||
- ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) )
+ ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) ||
+ (page_get_owner(page) != d) )
{
MEM_LOG("ptwr_emulate: Page is mistyped or bad pte (%p, %x)\n",
pte, page->u.inuse.type_info);
if ( cmpxchg((unsigned long *)pl1e, old, val) != old )
{
unmap_domain_mem(pl1e);
+ put_page_from_l1e(nl1e, d);
return X86EMUL_CMPXCHG_FAILED;
}
}
}
/* Finally, drop the old PTE. */
- if ( unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT) )
- put_page_from_l1e(ol1e, d);
+ put_page_from_l1e(ol1e, d);
return X86EMUL_CONTINUE;
}
/* We are looking only for read-only mappings of p.t. pages. */
if ( ((pte & (_PAGE_RW | _PAGE_PRESENT)) != _PAGE_PRESENT) ||
- ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) )
+ ((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) ||
+ (page_get_owner(page) != ed->domain) )
{
return 0;
}